﻿using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Threading;
using Logger4net;
using MS.Internal.Mita.Foundation;
using MS.Internal.Mita.Foundation.Collections;

namespace UIAStudio
{
    internal class SearchWorkItem : WorkItem
    {
        WorkQueue _workQueue;
        UIATreeNode _treeNode;
        UIObject _uiItem;
        bool _repopulated;
        Stack<UIObject> _routine;

        public SearchWorkItem(WorkQueue workQueue, UIATreeNode treeNode, UIObject item)
            : base(workQueue)
        {
            _repopulated = false;
            _workQueue = workQueue;
            _treeNode = treeNode;
            _uiItem = item;
        }

        public override void Execute()
        {
            if (_routine == null)
            {
                _routine = new Stack<UIObject>();
                _routine.Push(_uiItem);
                UIAncestors<UIObject> ancestors = new UIAncestors<UIObject>(_uiItem, UIObject.Factory);
                foreach(UIObject ancestor in ancestors)
                {
                    _routine.Push(ancestor);
                    Logger.Instance.Info("Push search stack: {0}", UIATreeNode.GetNodeName(ancestor));
                }
                _routine.Pop();
            }
            UIATreeNode foundNode = _treeNode.FindChild(_routine.Peek());
            if (foundNode == null)
            {
                if (!_repopulated)
                {
                    Logger.Instance.Info("Populate node:{0}", _treeNode.Text);
                    _repopulated = true;
                    PopulationWorkItem populationWorkItem = new PopulationWorkItem(Queue, _treeNode as UIATreeNode);
                    Queue.Enqueue(populationWorkItem);
                    Queue.Enqueue(this);
                    return;
                }
                else
                {
                    Logger.Instance.Error("Cannot able to find this UI: {0}!", UIATreeNode.GetNodeName(_routine.Peek()));
                    return;
                }
            }
            else
            {
                _repopulated = false;
                UIObject i = _routine.Peek();
                Logger.Instance.Info("Found node:{0}", UIATreeNode.GetNodeName(foundNode.UIObject));
                _routine.Pop();
                if (_routine.Count == 0)
                {
                    ThreadStart ts = delegate
                    {
                        Logger4net.Logger.Instance.Info("Select node.");
                        _treeNode.TreeView.SelectedNode = foundNode;
                    };
                    _treeNode.TreeView.Invoke(ts);
                    return;
                }
                else
                {
                    _treeNode = foundNode;
                    Queue.Enqueue(this);
                }
            }
        }
    }
}